var mongoose = require('mongoose'),
    fs = require('fs'),
    http = require('http'),
    BaseRoute = require('../routes/Base.server.routes'),
    BaseConst = require("./Const"),
    BaseEnum = require("./Enum"),
    socket = require('./Socket'),
    entityCollection = require('./EntityCollection'),
    Excel = require('exceljs');

exports.checkUser = function(user){
    if(user == undefined){
        return false;
    }

    return true;
};

exports.getErrMsgByRecord = function(entityName, record, msg){
    var newMsg = "";    //"表名：" + entityName + "\n";
    if(record.Name != undefined){
        newMsg += "名称：" + record.Name + "\n";
    }
    if(record.Code != undefined){
        newMsg += "编码：" + record.Code + "\n";
    }
    if(newMsg === ""){
        newMsg += "ID：" + record._id + "\n";
    }

    newMsg += "信息：\n  " + msg;
    return newMsg;
};

exports.authorizedCheck = function(user, res){
    if(!exports.checkUser(user)){
        var newErr = new Error();
        newErr.leval = 0;
        newErr.title = '用户验证失败';
        newErr.message = '登录超时，请重新登录';
        res.status(400).send(newErr);
        res.ends();
    }
};

exports.responseHandler = function(res) {
    return function (err, data) {
        exports.responseFun(res, err, data);
    };
};
exports.responseFun = function(res, err, data) {
    if (err) {
        exports.errorLog(err.title, err.message);
        res.json({ Error: err });
        // res.status(400).send({
        //     message: "错误信息"
        // });

    } else {
        res.json({ Data: data });
    }
    res.end();
};

module.exports.addRoute = function(url, controller, name, remark){
    BaseRoute.App.route(url).post(function(req, res){
        // console.log('start');
        controller(req, function(err, data) {
            if (err) {
                exports.errorLog(err.title, err.message);
                res.json({ Error: err });
            } else {
                // console.log('end');
                res.json({ Data: data });
            }
            res.end();
        });
    });
};

//将条件格式化处理
//比如：查询配送记录，条件：InputWork.Name = "aa"，会先将 InputWork.Name 转换为 Work.Name，
//因为没有InputWork实体，通过Schema找到InputWork对应的是Work字段，然后格式化正则表达式
exports.formatCondition = function(entityClass, condition, resultHandel){
    try{
        //获取字段对应的顶级属性条件
        var getFieldCondition = function(field, fieldCondition){
            var fields = field.split('.');
            var fieldEntity = null;   //被查找的实体，比如：Parent.Name，这里记录Parent所对应的Department实体
            var findEntitys = [];

            //找出字段对应的实体
            for(var i=0; i<fields.length; i++){
                if(i == 0){
                    fieldEntity = entityCollection.getEntity(entityClass.Fields[fields[0]].ref);
                }
                else{
                    findEntitys.push({
                        Entity: fieldEntity,
                        Field: fields[i]
                    });
                    //如果不是最后一个字段，都会有对应的实体
                    if(i != fields.length - 1){
                        fieldEntity = entityCollection.getEntity(fieldEntity.Fields[fields[i]].ref);
                    }
                }
            }

            //获取顶级属性对应的id集合条件
            var getFieldIds = function(entity, objCondition){   
                return new Promise(function(resolve, reject) {
                    entity.Entity.find(objCondition).exec(function(err, records) {
                        if (err) {
                            var newErr = new Error();
                            newErr.leval = 5;
                            newErr.title = '【' + entityName + '】' + '查找错误';
                            newErr.message = err.message;
                            reject(newErr);
                        }
                        else {
                            var ids = [];
                            for (var j = 0; j < records.length; j++) {
                                ids.push(records[j]._id);
                            }

                            if(findEntitys.length > 0){
                                var findParameter = findEntitys.splice(findEntitys.length - 1, 1)[0];
                                findWhere = {};
                                findWhere[findParameter.Field] = {$in: ids};
                                getFieldIds(findParameter.Entity, findWhere).then(function(data){
                                    resolve(data);
                                }).catch(err => reject(err));
                            }
                            else{
                                resolve({$in: ids});
                            }
                        }
                    });
                });
            };

            var findParameter = findEntitys.splice(findEntitys.length - 1, 1)[0];
            var findWhere = {};
            findWhere[findParameter.Field] = fieldCondition;

            return getFieldIds(findParameter.Entity, findWhere);
        };

        //将条件进行格式化，将传过来的正则表达式字符串转换为正则表达式
        var regexCondition = function(condition){
            // for(var p in condition){
            //     if(condition[p] != null) {
            //         if (condition[p].constructor == String) {
            //             if (condition[p].search(/^\/.*\/$/) > -1) {
            //                 condition[p] = new RegExp(condition[p].substring(1, condition[p].length - 1));
            //             }
            //         }
            //         else if (condition[p].constructor == Array) {
            //             for(var i=0; i<condition[p].length; i++){
            //                 condition[p][i] = regexCondition(condition[p][i]);
            //             }
            //         }
            //         else if (condition[p].constructor == Object) {
            //             condition[p] = regexCondition(condition[p]);
            //         }
            //     }
            // }

            return condition;
        };

        var promises = [];
        //遍历所有属性，将多级查询改为顶级属性对应的查询
        var getCondition = function(entityClass, condition){ 
            for(var p in condition) {
                var fieldAttributes = p.split('.');
                if(fieldAttributes.length > 1) {
                    promises.push(getFieldCondition(p, condition[p]).then(function(data){
                        delete condition[p];
                        condition[fieldAttributes[0]] = data;
                    }));
                }
                else{
                    if(condition[p] != null) {
                        if (condition[p].constructor == Array) {
                            for(var i=0; i<condition[p].length; i++){
                                if(condition[p][i].constructor == Object){
                                    getCondition(entityClass, condition[p][i]);
                                }
                            }
                        }
                    }
                }
            }
        };

        getCondition(entityClass, condition);

        Promise.all(promises).then(function(data){
            resultHandel(null, condition)
        }).catch(function(err){
            resultHandel({
                leval: 5,
                title: '数据库条件错误',
                message: "详细信息：条件：" + condition.toString() + '转换出错'
            });
        });
    }
    catch(e){
        resultHandel({
            leval: 5,
            title: '数据库条件错误',
            message: "详细信息：" + e.message + "\n" + "条件：" + condition.toString()
        });
    }
};


//记录错误日志
exports.errorLog = function(title, msg, strUser){
    exports.log(BaseEnum.LogType.Error, title, msg, strUser);
};
//记录访问日志
exports.accessLog = function(title, msg, strUser){
    exports.log(BaseEnum.LogType.Access, title, msg, strUser);
};
//记录执行日志
exports.executeLog = function(title, msg, strUser){
    exports.log(BaseEnum.LogType.Execute, title, msg, strUser);
};
//记录日志
exports.log = function(logType, title, msg, strUser){
    var strMsg;
    var nowDate = new Date();
    var fileFullName;
    var fileName = nowDate.getFullYear() + 
    '.' + (nowDate.getMonth() + 1 < 10 ? '0' + (nowDate.getMonth() + 1).toString() : (nowDate.getMonth() + 1).toString()) + 
    '.' + (nowDate.getDate() < 10 ? '0' + nowDate.getDate().toString() : nowDate.getDate().toString());

    strMsg = (nowDate.getHours().toString().length == 1 ? '0' + nowDate.getHours().toString() : nowDate.getHours().toString()) + 
        ":" + (nowDate.getMinutes().toString().length == 1 ? '0' + nowDate.getMinutes().toString() : nowDate.getMinutes().toString()) +  
        ":" + (nowDate.getSeconds().toString().length == 1 ? '0' + nowDate.getSeconds().toString() : nowDate.getSeconds().toString());

    if(strUser != undefined && strUser.trim() != ''){
        strMsg += ' 【' + strUser + '】';
    }
    
    if(logType == BaseEnum.LogType.Error){
        fileFullName = './logs/error/' + fileName + '.log';
        strMsg += '\r\n标题：' + title + '\r\n' + '错误信息：' + msg + '\r\n\r\n';
    }
    else if(logType == BaseEnum.LogType.Access){
        fileFullName = './logs/access/' + fileName + '.log';
        strMsg += '\r\n标题：' + title + '\r\n' + '访问信息：' + msg + '\r\n\r\n';
    }
    else if(logType == BaseEnum.LogType.Execute){
        fileFullName = './logs/execute/' + fileName + '.log';
        strMsg += '\r\n标题：' + title + '\r\n' + '执行信息：' + msg + '\r\n\r\n';
    }
    else{
        return;
    }

    fs.exists(fileFullName, function(isExist){
        if(isExist){
            fs.appendFile(fileFullName, strMsg, function(err, data) {
                if(err) {
                    console.log('日志文件追加信息出错【' + strUser + '】:' + '\r\n' + err.toString());
                }
            });
        }
        else{
            fs.writeFile(fileFullName, strMsg, function(err, data) {
                if(err) {
                    console.log('创建访问日志文件出错【' + strUser + '】:' + '\r\n' + err.toString());
                }
            });
        }
    });
};

exports.requestHttp = function(options, parameter){
    return new Promise(function(resolve, reject) {
        if(!options.path){
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '请求服务器错误';
            newErr.message = '没有传入路径参数';
            reject(newErr);
            return;
        }
        if(parameter){
            parameter = JSON.stringify(parameter);
        }
        if(!options.hostname){
            options.hostname = '127.0.0.1';
        }
        if(!options.port){
            options.port = 3000;
        }
        if(!options.method){
            options.method = 'POST';
        }
        if(!options.headers){
            options.headers = {
                 "Content-Type": 'application/json',
                 "Content-Length": parameter ? parameter.length : 0
            };
        }

        var req = http.request(options, function(res){
            var result = ''
            res.on('data', function(data){
                result += data;
            }).on('end', function(){
                result = JSON.parse(result);
                if(result.Error){
                    reject(result.Error);
                }
                else{
                    resolve(result.Data);
                }
            });
        });

        if(parameter){
            req.write(parameter);
        }

        req.on('error', (err) => {
            reject(err);
        });
        req.end();
    });
};

//下载文件
exports.downloadFile = function(serverPath, downloadFileName, fileName, deleteFileName, socketId, returnHandle){
    serverPath = serverPath.replace(/\\/g, "/");
    //去掉http头
    if(serverPath.indexOf('//') > -1){
        serverPath = serverPath.split('//')[1];
    }
    if(fileName == undefined || fileName == null || fileName.trim() == ''){
        fileName = downloadFileName;
    }
    
    var serverAddress = serverPath.substring(0, serverPath.indexOf('/'));   //文件服务器IP及Port
    var serverApiPath = serverPath.substring(serverPath.indexOf('/'), serverPath.length);     //文件服务器Api
    var serverHostName = serverAddress; //文件服务器地址
    var serverPort = 80;    //文件服务器端口
    if(serverAddress.indexOf(':') > 0){
        serverHostName = serverAddress.split(':')[0];
        serverPort = parseInt(serverAddress.split(':')[1]);
    }

    var parameter = {
        FileName: fileName
    };
    parameter = JSON.stringify(parameter);

    var options = {
        hostname: serverHostName,
        port: serverPort,
        path: serverApiPath,
        method: 'POST',
        headers: {
             "Content-Type": 'application/json',
             "Content-Length": parameter.length
        }
    };

    var fileFullPath = BaseConst.FilePath + fileName;

    //创建写入流
    var fileWriteStream = fs.createWriteStream(fileFullPath + '.temp');
    var httpRequest = http.request(options, function (httpResponse) {
        httpResponse.on('data', function(data){
            fileWriteStream.write(data);

            if(socketId != null && socketId != undefined && socketId.trim() != ""){
                socket.emitBySocketId(socketId, downloadFileName + "_DownloadSize", data.length);
            }
        });
        httpResponse.on('end', function(){
            fileWriteStream.end();
            if(deleteFileName != null && deleteFileName != undefined && deleteFileName.trim() != ''){
                //删除已有文件
                exports.fileDeleteSync(BaseConst.FilePath + deleteFileName);
            }
            //重命名
            exports.fileRenameSync(fileFullPath + '.temp', fileFullPath);
            if(socketId != null && socketId != undefined && socketId.trim() != ""){
                socket.emitBySocketId(socketId, downloadFileName + "_DownloadComplete", true);
            }
            returnHandle(null, {FileName: fileName});
        });
    });

    httpRequest.write(parameter);

    httpRequest.on('error', function (err) {
        returnHandle(err);
    });
    httpRequest.end();
};

//文件重命名
//异步
exports.fileRename = function(oldPath, newPath, completeFun){
    fs.exists(path, function(isExists) {
        if(isExists) {
            fs.rename(oldPath, newPath, function (err) {
                if (completeFun) {
                    completeFun(err);
                }
            });
        }
        else{
            var newErr = new Error();
            newErr.leval = 0;
            newErr.title = '重命名失败';
            newErr.message = '文件不存在';

            completeFun(newErr);
        }
    });
};
//同步
exports.fileRenameSync = function(oldPath, newPath){
    try{
        fs.renameSync(oldPath, newPath);
        return true;
    }
    catch(e){
        return false;
    }
};

//删除文件
//异步
exports.fileDelete = function(path, completeFun){
    fs.exists(path, function(isExists){
        if(isExists){ 
            //删除文件
            fs.unlink(path, function(err){
                completeFun(err);
            });
        }
        else{
            completeFun();
        }
    });
};
//同步
exports.fileDeleteSync = function(path){
    if(fs.existsSync(path)){
        try{
            fs.unlinkSync(path);
            return true;
        }
        catch(e){
            return false;
        }
    }
    else{
        return false;
    }
};

exports.getObjectId = function(){
    return mongoose.Types.ObjectId();
}
exports.getGuid = function(){
    return exports.getObjectId().toString();
};
exports.getGuids = function(num){
    var guids = [];
    for(var i=0; i<num; i++){
        guids.push(exports.getObjectId().toString());
    }
    return guids;
};

//将值按照舍入规则处理后返回
exports.formatNumber = function(val, round) {
    var returnValue;

    if(val == undefined || val == null || val.toString().trim() == ''){
        return '';
    }
    else if(round){
        if (round.RoundType == BaseEnum.RoundType.AllAdd.Value) {
            returnValue = parseInt(val * Math.pow(10, round.Precision + 1));

            if (returnValue % 10 > 0) {
                returnValue = parseInt(val * Math.pow(10, round.Precision)) + 1;
            }

            returnValue = returnValue / Math.pow(10, round.Precision);
        }
        else if (round.RoundType == BaseEnum.RoundType.AllDelete.Value) {
            returnValue = parseInt(val * Math.pow(10, round.Precision)) / Math.pow(10, round.Precision);
        }
        else {
            returnValue = parseInt(val * Math.pow(10, round.Precision + 1));

            if (returnValue % 10 >= round.RoundValue) {
                returnValue = parseInt(val * Math.pow(10, round.Precision)) + 1;
            }
            else {
                returnValue = parseInt(returnValue / 10);
            }
            returnValue = returnValue / Math.pow(10, round.Precision);
        }
        return parseFloat(returnValue).toFixed(round.Precision);
    }
    else{
        return val;
    }    
};

//异步创建Excel
//https://github.com/guyonroche/exceljs#create-a-workbook
exports.createExcel = function(workbookData, completeFun){
    var guid = exports.getObjectId();
    if(workbookData.FileName == undefined || workbookData.FileName == null || workbookData.FileName.trim() == ''){
        workbookData.FileName = exports.getGuid().replace(/-/g, '') + ".xlsx";
    }
    else{
        workbookData.FileName = workbookData.FileName.split(".")[0] + ".xlsx";
    }

    //汇总类型
    var TotalTypeEnum = {
        Sum: {Value: 0, Text: '求和'},
        Average: {Value: 1, Text: '平均'}
    };

    //将数字转换成Excel对应的列号（ABC字符串）
    var columnIndexToChar = function(number){
        var str = '';
        while (number > 0){
            var m = number % 26;
            if (m == 0){
                m = 26;
            }
            str = String.fromCharCode(m + 64) + str;
            number = (number - m) / 26;
        }
        return str;
    };

    //获取每列所所需的数据，组合形成新的行数据
    var getSheetRowValues = function(record, sheetColumns){
        var rowValues = {};
        for(var i=0; i<sheetColumns.length; i++){
            var cellValue = null;
            try{
                cellValue = eval('record.' + sheetColumns[i].Key);
            }
            catch(e){
            }
            finally{
                if(sheetColumns[i].Type == BaseEnum.ValueType.String.Value){
                    if(cellValue == null){
                        cellValue = '';
                    }
                }
                else if(sheetColumns[i].Type == BaseEnum.ValueType.Number.Value){
                    if(cellValue == null){
                        cellValue = '';
                    }
                    else{
                        cellValue = exports.formatNumber(cellValue, sheetColumns[i].Round);
                    }
                }
                else if(sheetColumns[i].Type == BaseEnum.ValueType.Percent.Value){
                    if(cellValue == null){
                        cellValue = '';
                    }
                    else{
                        cellValue = exports.formatNumber(cellValue * 100, sheetColumns[i].Round).toString() + '%';
                    }
                }
                else if(sheetColumns[i].Type == BaseEnum.ValueType.Boolean.Value){
                    if(cellValue){
                        cellValue = '√';
                    }
                    else{
                        cellValue = '';
                    }
                }
                else if(sheetColumns[i].Type == BaseEnum.ValueType.Date.Value){
                    if(cellValue == null){
                        cellValue = '';
                    }
                    else{
                        var dateValue = new Date(cellValue);
                        cellValue = dateValue.getFullYear() + 
                            '.' + (dateValue.getMonth() + 1 < 10 ? '0' + (dateValue.getMonth() + 1).toString() : (dateValue.getMonth() + 1).toString()) + 
                            '.' + (dateValue.getDate() < 10 ? '0' + dateValue.getDate().toString() : dateValue.getDate().toString());
                        if(sheetColumns[i].DateTimeFormat != BaseEnum.DateTimeFormat.Date.Value){
                            cellValue += ' ' + (dateValue.getHours().toString().length == 1 ? '0' + dateValue.getHours().toString() : dateValue.getHours().toString()) + 
                            ":" + (dateValue.getMinutes().toString().length == 1 ? '0' + dateValue.getMinutes().toString() : dateValue.getMinutes().toString()) +  
                            ":" + (dateValue.getSeconds().toString().length == 1 ? '0' + dateValue.getSeconds().toString() : dateValue.getSeconds().toString());
                        }
                    }
                }
                else if(sheetColumns[i].Type == BaseEnum.ValueType.Enum.Value){
                     if(sheetColumns[i].Enum){
                        var isFind = false;
                        for(var p in sheetColumns[i].Enum){
                            if(sheetColumns[i].Enum[p].Value == cellValue){
                                cellValue = sheetColumns[i].Enum[p].Text;
                                isFind = true;
                                break;
                            }
                        }
                        if(!isFind){
                            cellValue = '';
                        }
                    }
                }
            }
            rowValues[sheetColumns[i].Key] = cellValue;
        }
        return rowValues;
    };

    //将样式赋给单元格
    var setCellStyle = function(cell, style){
        for(var p in style){
            cell[p] = style[p];
        }
    };

    //给Worksheet创建新行
    var createRow = function(worksheet, rowData){
        var rowValues = [];
        for(var m=0; m<rowData.Cells.length; m++){
            rowValues.push(rowData.Cells[m].Value);
        }
        var sheetRow = worksheet.addRow(rowValues);
        sheetRow.height = rowData.Height;
        //对每个单元格赋样式
        for(var n=0; n<rowData.Cells.length; n++){
            var sheetCell = sheetRow.getCell(n+1);
            setCellStyle(sheetCell, rowData.Cells[n].Style);
            if(rowData.Cells[n].MergeCells != null && rowData.Cells[n].MergeCells != ''){
                worksheet.mergeCells(rowData.Cells[n].MergeCells);
            }
        }
    };

    //获取行数据
    var getRowValues = function(dataSource, completeFun){
        if(dataSource.DataBase.EntityName != null && dataSource.DataBase.EntityName != ''){
            var findParameter = dataSource.DataBase;
            var entity = entityCollection.getEntity(findParameter.EntityName);
            if(entity != null && entity != undefined){
                entity.find(findParameter.Condition, findParameter.OrderBy, findParameter.Populate, function(err, records) {
                    if (err) {
                        var newErr = new Error();
                        newErr.leval = 5;
                        newErr.title = '创建Excel：【' + findParameter.EntityName + '】' + '查找错误';
                        newErr.message = err.message;
                        if (completeFun != null && completeFun != undefined) {
                            completeFun(newErr);
                        }
                        return;
                    }
                    else {
                        completeFun(null, records);
                    }
                });
            }
        }
        else{
            completeFun(null, dataSource.Records);
        }
    };

    //当Worksheet创建完毕调用的方法，通知Workbook检查是否所有的Worksheet是否创建完毕，如果是则生成Excel
    var worksheetComplete = function(){
        var isCreateComplete = true;
        for(var i=0; i<workbookData.Worksheets.length; i++){
            if(!workbookData.Worksheets[i]["IsCreateSheet"]){
                isCreateComplete = false;
                break
            }
        }

        if(isCreateComplete){
            workbook.xlsx.writeFile(BaseConst.FilePath + workbookData.FileName).then(
                function() {
                    completeFun(null, {
                        FileName: workbookData.FileName,
                        CreatedBy: workbook.creator,
                        CreatedOn: workbook.created,
                        ModifyBy: workbook.modified,
                        LastModifiedBy: workbook.lastModifiedBy,
                        LastPrinted: workbook.lastPrinted
                    });
                },
                function(err){
                    var newErr = new Error();
                    newErr.leval = 0;
                    newErr.title = "生成" + workbookData.FileName + "出错";
                    newErr.message = err.message;
                    completeFun(newErr);
                }
            ).catch(function(err) {
                var newErr = new Error();
                newErr.leval = 0;
                newErr.title = "生成" + workbookData.FileName + "出错";
                newErr.message = err.message;
                completeFun(newErr);
            });
        }
    }

    var lineNumberField = '#$LineNumber$#'; //行号字段名

    //Create a Workbook
    var workbook = new Excel.Workbook();
    workbook.creator = workbookData.CreatedBy;  //创建人
    workbook.created = new Date();              //创建时间
    workbook.modified = '';                     //修改人
    workbook.lastModifiedBy = '';               //修改时间
    workbook.lastPrinted = null;                //最后打印时间，new Date(2016, 11, 9)    

    for(var i=0; i<workbookData.Worksheets.length; i++){
        workbookData.Worksheets[i]["IsCreateSheet"] = false;
    }

    //Create Worksheets
    if(workbookData.Worksheets.length > 0){
        for(var i=0; i<workbookData.Worksheets.length; i++){
            var worksheetData = workbookData.Worksheets[i];
            if(!worksheetData.Name){
                worksheetData.Name = 'Sheet' + (i+1).toString();
            }

            //Add a Worksheet
            var worksheet = workbook.addWorksheet(worksheetData.Name, {properties: {showGridLines: true}});

            var headerRowData = null;
            var headerRowDataIndex = null;
            //定义列格式
            for(var j=0; j<worksheetData.Rows.length; j++){
                if(worksheetData.Rows[j].IsHeaderRow){
                    headerRowData = worksheetData.Rows[j];
                    headerRowDataIndex = j;
                    var sheetColumns = [];
                    if(worksheetData.IsLineNumber){
                        sheetColumns.push({ 
                            header: '行号', 
                            key: lineNumberField, 
                            width: 5
                        });
                    }
                    for(var m=0; m<headerRowData.Cells.length; m++){
                        var newColumn = { 
                            header: headerRowData.Cells[m].Value, 
                            key: headerRowData.Cells[m].Key, 
                            width: headerRowData.Cells[m].Width
                        };

                        sheetColumns.push(newColumn);
                    }

                    //Columns
                    worksheet.columns = sheetColumns;   //定义列，会自动产生头行
                    worksheet.spliceRows(0, 1);         //删除头行的目的是为了使用column的列宽

                    //Frozen Views
                    worksheet.views = [
                        {
                            state: 'frozen',        //冻结窗口状态
                            xSplit: worksheetData.IsLineNumber ? 1 : 0,         //横向单元格数
                            ySplit: j + 1            //纵向单元格数
                            // topLeftCell: 'G5',    //右侧区域第一个显示的单元格
                            // activeCell: 'A1'      //默认选中单元格
                            // style: {
                            //     border: {
                            //         top: {style:'thin', color: {argb:'1E93DE'}},
                            //         left: {style:'thin', color: {argb:'1E93DE'}},
                            //         bottom: {style:'thin', color: {argb:'1E93DE'}},
                            //         right: {style:'thin', color: {argb:'1E93DE'}}
                            //     }
                            // }
                        }
                    ];
                    break;
                }
            };

            for(var j=0; j<headerRowDataIndex+1; j++){
                if(worksheetData.Rows[j].IsHeaderRow){
                    //1，添加标题行
                    var titleRowData = [];
                    if(worksheetData.IsLineNumber){
                        titleRowData.push('行号');
                    }
                    for(var m=0; m<headerRowData.Cells.length; m++){
                        titleRowData.push(headerRowData.Cells[m].Value);
                    }
                    var sheetHeaderRow = worksheet.addRow(titleRowData);
                    sheetHeaderRow.height = headerRowData.Height;
                    if(worksheetData.IsLineNumber){
                        var lineNumCell = sheetHeaderRow.getCell(1);
                        setCellStyle(lineNumCell, headerRowData.Cells[0].Style);
                    }
                    //对每个单元格赋样式
                    for(var n=0; n<headerRowData.Cells.length; n++){
                        if(worksheetData.IsLineNumber){
                            setCellStyle(sheetHeaderRow.getCell(n+2), headerRowData.Cells[n].Style);
                        }
                        else{
                            setCellStyle(sheetHeaderRow.getCell(n+1), headerRowData.Cells[n].Style);
                        }
                    }

                    //2，添加数据行
                    getRowValues(worksheetData.DataSource, function(err, records){
                        if(err){
                            completeFun(err);
                        }
                        else{
                            for(var m=0; m<records.length; m++){
                                // 新增数据行
                                var rowData = getSheetRowValues(records[m], headerRowData.Cells);
                                if(worksheetData.IsLineNumber){
                                    rowData[lineNumberField] = m + 1;
                                }
                                var sheetRow = worksheet.addRow(rowData);
                                //对每个单元格赋样式
                                for(var n=0; n<headerRowData.Cells.length; n++){
                                    if(worksheetData.IsLineNumber){
                                        setCellStyle(sheetRow.getCell(n+2), headerRowData.Cells[n].DataCellStyle);
                                    }
                                    else{
                                        setCellStyle(sheetRow.getCell(n+1), headerRowData.Cells[n].DataCellStyle);
                                    }
                                }
                                if(worksheetData.IsLineNumber){
                                    var lineNumCell = sheetRow.getCell(1);
                                    lineNumCell.alignment = {horizontal: 'right'};
                                    lineNumCell.font = headerRowData.Cells[0].DataCellStyle.font;
                                    lineNumCell.border = headerRowData.Cells[0].DataCellStyle.border;
                                    lineNumCell.fill = {
                                        type: 'pattern',
                                        pattern:'solid',
                                        fgColor:{argb:'fbf3de'},    //背景色
                                        bgColor:{argb:'000000'}
                                    };
                                }
                            }

                            //3, 添加汇总行
                            if(headerRowData.IsTotal){
                                var totalRowData = new Array();
                                if(worksheetData.IsLineNumber){
                                    totalRowData.push('汇总');
                                }
                                var totalRow = worksheet.addRow(totalRowData);
                                setCellStyle(totalRow.getCell(1),  {
                                    font: {
                                        family: 4,
                                        name: '宋体',
                                        size: 10,
                                        color: { argb: '1E93DE' },
                                        underline: false,
                                        bold: true
                                    },
                                    alignment: {
                                        vertical: 'middle',
                                        horizontal: 'center'
                                    },
                                    border: {
                                        top: {style:'thin', color: {argb:'1E93DE'}},
                                        left: {style:'thin', color: {argb:'1E93DE'}},
                                        bottom: {style:'thin', color: {argb:'1E93DE'}},
                                        right: {style:'thin', color: {argb:'1E93DE'}}
                                        //diagonal: {up: true, down: true, style:'thick', color: {argb:'FFFF0000'}}     //单元格打'X'
                                    },
                                    fill: {
                                        type: 'pattern',
                                        pattern:'solid',
                                        fgColor:{argb:'EFEFEF'},    //背景色
                                        bgColor:{argb:'FFFFFF'}
                                    }
                                });
                                for(var m=0; m<headerRowData.Cells.length; m++){
                                    var totalRowCell;
                                    if(worksheetData.IsLineNumber){
                                        totalRowCell = totalRow.getCell(m+2);
                                    }
                                    else{
                                        totalRowCell = totalRow.getCell(m+1);
                                    }
                                    totalRowCell.alignment = headerRowData.Cells[m].DataCellStyle.alignment;
                                    totalRowCell.font = headerRowData.Cells[m].DataCellStyle.font;
                                    totalRowCell.border = headerRowData.Cells[m].DataCellStyle.border;
                                    totalRowCell.fill = {
                                        type: 'pattern',
                                        pattern:'solid',
                                        fgColor:{argb:'fbf3de'},    //背景色
                                        bgColor:{argb:'000000'}
                                    };
                                    if(headerRowData.Cells[m].TotalType != null){
                                        var cellValue = 0;
                                        var columnChar = columnIndexToChar(m + 2);  //获取列号
                                        if(headerRowData.Cells[m].TotalType.Value == TotalTypeEnum.Sum.Value){
                                            // totalRowCell.value = { 
                                            //     formula: 'SUM(' + columnChar + (j+2).toString() + ':' + columnChar + (j+1+dataCount).toString() + ')'
                                            // };

                                            
                                            for(var n=0; n<records.length; n++){
                                                if(records[n][headerRowData.Cells[m].Key] != null && 
                                                    records[n][headerRowData.Cells[m].Key] != undefined){
                                                    cellValue += records[n][headerRowData.Cells[m].Key];
                                                }
                                            }
                                        }
                                        else if(headerRowData.Cells[m].TotalType.Value == TotalTypeEnum.Average.Value){
                                            // totalRowCell.value = { 
                                            //     formula: 'AVERAGE(' + columnChar + (j+2).toString() + ':' + columnChar + (j+1+dataCount).toString() + ')'
                                            // };

                                            for(var n=0; n<records.length; n++){
                                                if(records[n][headerRowData.Cells[m].Key] != null && 
                                                    records[n][headerRowData.Cells[m].Key] != undefined){
                                                    cellValue += records[n][headerRowData.Cells[m].Key];
                                                }
                                            }
                                            cellValue = cellValue / records.length;
                                        }

                                        if(headerRowData.Cells[m].Type == BaseEnum.ValueType.Number.Value){
                                            totalRowCell.value = exports.formatNumber(cellValue, headerRowData.Cells[m].Round);
                                        }
                                        else if(headerRowData.Cells[m].Type == BaseEnum.ValueType.Percent.Value){
                                            totalRowCell.value = exports.formatNumber(cellValue * 100, headerRowData.Cells[m].Round).toString() + '%';
                                        }
                                    }
                                }
                            }

                            //4，创建剩下的自定义行
                            for(var m=headerRowDataIndex+1; m<worksheetData.Rows.length; m++){
                                createRow(worksheet,worksheetData.Rows[m]);
                            }

                            worksheetData["IsCreateSheet"] = true;
                            worksheetComplete();
                        }
                    });

                    break;
                }
                else{
                    createRow(worksheet, worksheetData.Rows[j]);
                }
            }

            if(headerRowData == null){
                workbookData.Worksheets[i]["IsCreateSheet"] = true;
                worksheetComplete();
            }
        }
    }
    else{
        worksheetComplete();
    }
};
